﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;

namespace Chengqbd.Core.Extensions
{
	public static class DictionaryExtensions
	{
        /// <summary>
        /// 返回对象
        /// </summary>
        /// <typeparam name="TKey"></typeparam>
        /// <typeparam name="TValue"></typeparam>
        /// <param name="dictionary"></param>
        /// <param name="key"></param>
        /// <param name="defaultValue"></param>
        /// <returns></returns>
		public static TValue GetOrDefault<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, TKey key, TValue defaultValue = default(TValue))
		{
			TValue tvalue;
			return dictionary.TryGetValue(key, out tvalue) ? tvalue : defaultValue;
		}
        /// <summary>
        /// 批量添加
        /// </summary>
        /// <typeparam name="TKey"></typeparam>
        /// <typeparam name="TValue"></typeparam>
        /// <param name="dict"></param>
        /// <param name="values"></param>
        /// <param name="replaceExisted"></param>
        /// <returns></returns>
		public static IDictionary<TKey, TValue> AddRange<TKey, TValue>(this IDictionary<TKey, TValue> dict, IEnumerable<KeyValuePair<TKey, TValue>> values, bool replaceExisted)
		{
			foreach (KeyValuePair<TKey, TValue> keyValuePair in values)
			{
				bool flag = dict.ContainsKey(keyValuePair.Key) && replaceExisted;
				if (flag)
				{
					dict[keyValuePair.Key] = keyValuePair.Value;
				}
				else
				{
					bool flag2 = !dict.ContainsKey(keyValuePair.Key);
					if (flag2)
					{
						dict.Add(keyValuePair.Key, keyValuePair.Value);
					}
				}
			}
			return dict;
		}
        /// <summary>
        /// 存在返回值，不存在刚添加
        /// </summary>
        /// <typeparam name="TKey"></typeparam>
        /// <typeparam name="TValue"></typeparam>
        /// <param name="dict"></param>
        /// <param name="key"></param>
        /// <param name="setValue"></param>
        /// <returns></returns>
		public static TValue GetOrAdd<TKey, TValue>(this IDictionary<TKey, TValue> dict, TKey key, Func<TKey, TValue> setValue)
		{
			TValue tvalue;
			bool flag = !dict.TryGetValue(key, out tvalue);
			if (flag)
			{
				tvalue = setValue(key);
				dict.Add(key, tvalue);
			}
			return tvalue;
		}
        /// <summary>
        /// 存在返回值，不存在刚添加
        /// </summary>
        /// <typeparam name="TKey"></typeparam>
        /// <typeparam name="TValue"></typeparam>
        /// <param name="dictionary"></param>
        /// <param name="key"></param>
        /// <param name="addFunc"></param>
        /// <returns></returns>
		public static TValue GetOrAdd<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, TKey key, Func<TValue> addFunc)
		{
			TValue tvalue;
			bool flag = dictionary.TryGetValue(key, out tvalue);
			TValue result;
			if (flag)
			{
				result = tvalue;
			}
			else
			{
				result = (dictionary[key] = addFunc());
			}
			return result;
		}
        /// <summary>
        /// 排序 
        /// </summary>
        /// <typeparam name="TKey"></typeparam>
        /// <typeparam name="TValue"></typeparam>
        /// <param name="dictionary"></param>
        /// <returns></returns>
		public static IDictionary<TKey, TValue> Sort<TKey, TValue>(this IDictionary<TKey, TValue> dictionary)
		{
			bool flag = dictionary == null;
			if (flag)
			{
				throw new ArgumentNullException("dictionary");
			}
			return new SortedDictionary<TKey, TValue>(dictionary);
		}
        /// <summary>
        /// 排序
        /// </summary>
        /// <typeparam name="TKey"></typeparam>
        /// <typeparam name="TValue"></typeparam>
        /// <param name="dictionary"></param>
        /// <param name="comparer"></param>
        /// <returns></returns>
		public static IDictionary<TKey, TValue> Sort<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, IComparer<TKey> comparer)
		{
			bool flag = dictionary == null;
			if (flag)
			{
				throw new ArgumentNullException("dictionary");
			}
			bool flag2 = comparer == null;
			if (flag2)
			{
				throw new ArgumentNullException("comparer");
			}
			return new SortedDictionary<TKey, TValue>(dictionary, comparer);
		}
        /// <summary>
        /// 以值排序
        /// </summary>
        /// <typeparam name="TKey"></typeparam>
        /// <typeparam name="TValue"></typeparam>
        /// <param name="dictionary"></param>
        /// <returns></returns>
		public static IDictionary<TKey, TValue> SortByValue<TKey, TValue>(this IDictionary<TKey, TValue> dictionary)
		{
			return (from x in new SortedDictionary<TKey, TValue>(dictionary)
			orderby x.Value
			select x).ToDictionary((KeyValuePair<TKey, TValue> x) => x.Key, (KeyValuePair<TKey, TValue> x) => x.Value);
		}
        /// <summary>
        /// 顺序生成string
        /// </summary>
        /// <typeparam name="TKey"></typeparam>
        /// <typeparam name="TValue"></typeparam>
        /// <param name="dictionary"></param>
        /// <param name="separator"></param>
        /// <returns></returns>
		public static string ToQueryString<TKey, TValue>(this IDictionary<TKey, TValue> dictionary)
		{
			bool flag = dictionary == null || !dictionary.Any<KeyValuePair<TKey, TValue>>();
			string result;
			if (flag)
			{
				result = string.Empty;
			}
			else
			{
				StringBuilder stringBuilder = new StringBuilder();
				foreach (KeyValuePair<TKey, TValue> keyValuePair in dictionary)
				{
					StringBuilder stringBuilder2 = stringBuilder;
					TKey key = keyValuePair.Key;
					string str = key.ToString();
					string str2 = "=";
					TValue value = keyValuePair.Value;
					stringBuilder2.Append(str + str2 + value.ToString() + "&");
				}
				result = stringBuilder.ToString().TrimEnd(new char[]
				{
					'&'
				});
			}
			return result;
		}
        /// <summary>
        /// 顺序生成string
        /// </summary>
        /// <typeparam name="TKey"></typeparam>
        /// <typeparam name="TValue"></typeparam>
        /// <param name="dictionary"></param>
        /// <param name="separator"></param>
        /// <returns></returns>
		public static string ToQueryString<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, string separator)
		{
			bool flag = dictionary == null || !dictionary.Any<KeyValuePair<TKey, TValue>>();
			string result;
			if (flag)
			{
				result = string.Empty;
			}
			else
			{
				StringBuilder stringBuilder = new StringBuilder();
				foreach (KeyValuePair<TKey, TValue> keyValuePair in dictionary)
				{
					StringBuilder stringBuilder2 = stringBuilder;
					TKey key = keyValuePair.Key;
					string str = key.ToString();
					string str2 = "=";
					TValue value = keyValuePair.Value;
					stringBuilder2.Append(str + str2 + value.ToString() + separator);
				}
				result = stringBuilder.ToString();
			}
			return result;
		}
        /// <summary>
        /// 读取元素
        /// </summary>
        /// <typeparam name="TKey"></typeparam>
        /// <typeparam name="TValue"></typeparam>
        /// <param name="dictionary"></param>
        /// <param name="value"></param>
        /// <returns></returns>
		public static TKey GetKey<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, TValue value)
		{
        
            bool predicate(KeyValuePair<TKey, TValue> m) => m.Value.Equals(value);
            using (IEnumerator<KeyValuePair<TKey, TValue>> enumerator = dictionary.Where(predicate).GetEnumerator())
			{
				if (enumerator.MoveNext())
				{
					KeyValuePair<TKey, TValue> keyValuePair = enumerator.Current;
					return keyValuePair.Key;
				}
			}
			return default(TKey);
		}
        /// <summary>
        /// 添加元素
        /// </summary>
        /// <typeparam name="TKey"></typeparam>
        /// <typeparam name="TValue"></typeparam>
        /// <param name="dictionary"></param>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <returns></returns>
		public static IDictionary<TKey, TValue> TryAdd<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, TKey key, TValue value)
		{
			bool flag = !dictionary.ContainsKey(key);
			if (flag)
			{
				dictionary.Add(key, value);
			}
			return dictionary;
		}
        /// <summary>
        /// 转换hash表
        /// </summary>
        /// <typeparam name="TKey"></typeparam>
        /// <typeparam name="TValue"></typeparam>
        /// <param name="dictionary"></param>
        /// <returns></returns>
		public static Hashtable ToHashTable<TKey, TValue>(this IDictionary<TKey, TValue> dictionary)
		{
			Hashtable hashtable = new Hashtable();
			foreach (KeyValuePair<TKey, TValue> keyValuePair in dictionary)
			{
				hashtable.Add(keyValuePair.Key, keyValuePair.Value);
			}
			return hashtable;
		}
        /// <summary>
        /// key value倒置
        /// </summary>
        /// <typeparam name="TKey"></typeparam>
        /// <typeparam name="TValue"></typeparam>
        /// <param name="dictionary"></param>
        /// <returns></returns>
		public static IDictionary<TValue, TKey> Reverse<TKey, TValue>(this IDictionary<TKey, TValue> dictionary)
		{
			bool flag = dictionary == null;
			if (flag)
			{
				throw new ArgumentNullException("dictionary");
			}
			return dictionary.ToDictionary((KeyValuePair<TKey, TValue> x) => x.Value, (KeyValuePair<TKey, TValue> x) => x.Key);
		}
        
		public static IReadOnlyDictionary<TKey, TValue> AsReadOnly<TKey, TValue>(this IDictionary<TKey, TValue> dictionary)
		{
			return new ReadOnlyDictionary<TKey, TValue>(dictionary);
		}
	}
}
